package com.weixin.common.utils;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.LocalDateTimeUtil;
import org.apache.commons.lang3.time.DateUtils;

import java.security.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * 时间工具类
 *
 * @author zh
 */
public class DateUtil extends DatePattern {

    //时间格式
    public static final String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
    public static final String YYYYMMDD_HHMMSS = "yyyy-MM-dd HH:mm:ss";
    public static final String YYYYMMDDHHMMSSSSS = "yyyyMMddHHmmssSSS";
    public static final String MMDDHHMMSSSSS = "MMddHHmmssSSS";
    public static final String YYYY_MM = "yyyy-MM";
    public static final String YYYY_MM_DD = "yyyy-MM-dd";
    public static final String YYYY_MM_DD_SLA = "yyyy/MM/dd";
    public static final String MM_DD_SLA = "MM/dd";
    public static final String YYYY_MM_SLA= "yyyy/MM";

    public static final String YYYY_M_D_SLA = "yyyy/M/d";
    public static final String YYYYMMDD = "yyyyMMdd";
    public static final String YYYYDOTMMDD = "yyyy.MM.dd";
    public static final String YYYYM = "yyyy年M月";
    private final static String LINK_CHAR = "-";

    /**
     * 带斜杠的简易日期格式
     */
    public static final String DATE_SIMPLE = "yyyy/MM/dd";
    /**
     * 带斜杠的简易日期时间格式，到分钟
     */
    public static final String DATE_MINUTE_SIMPLE = "yyyy/MM/dd HH:mm";

    public static final String YYYYMMDD_T_HHMMSS = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";



    private static String[] parsePatterns = {"yyyy-MM-dd", "yyyy年MM月dd日",
            "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy/MM/dd",
            "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyyMMdd"};


    /**
     * 日期转换-  String -> Date
     *
     * @param dateString 字符串时间
     * @return Date类型信息
     * @throws ParseException 抛出异常
     */
    public static Date parseString2Date(String dateString) throws ParseException {
        if (dateString == null) {
            return null;
        }
        return parseString2Date(dateString);
    }

    /**
     * 日期转换 String -> LocalDate
     *
     * @param dateString 字符串时间
     * @return $return
     */
    public static LocalDate parseString2LocalDate(String dateString) {
        if (dateString == null) {
            return null;
        }
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy/M/d");
        return LocalDate.parse(dateString, fmt);
    }

    /**
     * 日期转换 String -> LocalDate
     *
     * @param dateString str
     * @param format     格式
     * @return java.time.LocalDate
     * @author wangchunhui
     * @date 2023/8/10 16:37
     */
    public static LocalDate parseString2LocalDateByFormat(String dateString, String format) {
        if (dateString == null) {
            return null;
        }
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern(format);
        return LocalDate.parse(dateString, fmt);
    }

    /**
     * 日期转换 String -> LocalDate
     *
     * @param dateString str
     * @param format     格式
     * @return java.time.LocalDate
     * @author wangchunhui
     * @date 2023/8/10 16:37
     */
    public static LocalDateTime parseStringToLocalDateTime(String dateString, String format) {
        if (dateString == null) {
            return null;
        }
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern(format);
        return LocalDateTime.parse(dateString, fmt);
    }

    /**
     * 日期转换-  String -> Date
     *
     * @param dateString 字符串时间
     * @param pattern    格式模板
     * @return Date类型信息
     * @throws ParseException 抛出异常
     */
    public static Date parseString2Date(String dateString, String pattern) throws ParseException {
        if (dateString == null) {
            return null;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Date date = sdf.parse(dateString);
        return date;
    }

    /**
     * 日期转换 LocalDate -> String
     *
     * @param date    LocalDate
     * @param pattern 格式模板
     * @return java.lang.String
     * @author wangchunhui
     * @date 2023/8/11 10:13
     */
    public static String parseDate2String(LocalDate date, String pattern) {
        if (Objects.isNull(date)) {
            return "";
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
        return date.format(formatter);
    }

    /**
     * 将月份字符串转为带年月
     *
     * @param monthStr 月份字符串
     * @param pattern  格式模板
     * @return java.lang.String
     * @author wangchunhui
     * @date 2023/12/25 17:28
     */
    public static String parseMonthStr2String(String monthStr, String pattern) {
        if (Objects.isNull(monthStr)) {
            return "";
        }
        // 定义输入和输出的日期格式
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern(YYYY_MM);
        DateTimeFormatter outputFormatter = DateTimeFormatter.ofPattern(pattern);
        // 解析输入字符串为YearMonth对象
        YearMonth yearMonth = YearMonth.parse(monthStr, inputFormatter);
        return yearMonth.format(outputFormatter);
    }

    /**
     * 当前日期转换 Date -> String
     *
     * @param pattern 格式模板
     * @return 字符串时间
     * @throws ParseException 抛出异常
     */
    public static String parseNowDateToString(String pattern) {
        if (pattern == null) {
            return null;
        }
        LocalDateTime localDateTime = LocalDateTime.now();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(pattern);
        return localDateTime.format(dtf);
    }

    public static String getFirstDayOfMonth(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month - 1);
        //获取某月最小天数
        int firstDay = cal.getMinimum(Calendar.DATE);
        cal.set(Calendar.DAY_OF_MONTH, firstDay);
        SimpleDateFormat sdf = new SimpleDateFormat("MM.dd");
        return sdf.format(cal.getTime());
    }

    public static String getLastDayOfMonth1(int year, int month) {
        Calendar cal = Calendar.getInstance();
        //设置年份
        cal.set(Calendar.YEAR, year);
        //设置月份
        cal.set(Calendar.MONTH, month - 1);
        //获取某月最大天数
        int lastDay = cal.getActualMaximum(Calendar.DATE);
        cal.set(Calendar.DAY_OF_MONTH, lastDay);
        SimpleDateFormat sdf = new SimpleDateFormat("MM.dd");
        return sdf.format(cal.getTime());
    }

    public static String getStrMonth(int month) {
        String[] strs = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"};
        if (month > 0 && month < 13) {
            return strs[month - 1];
        } else {
            return "一";
        }
    }

    public static String parseTimestampToStr(Timestamp timestamp, String timeFromat) {
        SimpleDateFormat df = new SimpleDateFormat(timeFromat);
        return df.format(timestamp);
    }

    public static String timestampToDate(long time, String timeFormat) {
        if (time < 10000000000L) {
            time = time * 1000;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(timeFormat);
        String sd = sdf.format(new Date(Long.parseLong(String.valueOf(time))));
        return sd;
    }

    public static List<String> getYearMonths() throws Exception {
        ArrayList<String> result = new ArrayList<String>();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");//格式化为年月

        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();
        min.set(min.get(Calendar.YEAR), 0, 1);

        max.setTime(new Date());
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

        Calendar curr = max;

        while (curr.after(min)) {
            result.add(sdf.format(curr.getTime()));
            curr.add(Calendar.MONTH, -1);
        }

        return result;
    }

    public static String[] getDaysByYearMonth(String yearMonth) throws ParseException {
        Date date = new SimpleDateFormat("yyyyMM").parse(yearMonth);
        Calendar a = Calendar.getInstance();
        a.setTime(date);
        a.set(Calendar.DATE, 1);
        a.roll(Calendar.DATE, -1);
        int maxDate = a.get(Calendar.DATE);
        String[] days = new String[maxDate];
        for (int i = 0; i < maxDate; i++) {
            String day = (i + 1) < 10 ? "0" + (i + 1) : (i + 1) + "";
            days[i] = yearMonth + day;
        }
        return days;
    }

    public static boolean comparingDate(String targer, Date sourceDate) throws Exception {

        Date date1 = new SimpleDateFormat("HH:mm:ss").parse(targer);

        String t = new SimpleDateFormat("HH:mm:ss").format(sourceDate);

        Date date2 = new SimpleDateFormat("HH:mm:ss").parse(t);

        return date1.after(date2);
    }

    public static boolean isWeekend(String time) throws ParseException {
        ;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(parseString2Date(time, "yyyyMMdd"));
        int i = calendar.get(Calendar.DAY_OF_WEEK) - 1;
        return i == 0 ? true : i == 5 ? true : false;
    }

    /**
     * 获取当前时间
     */
    public static LocalDateTime getNow() {
        return LocalDateTime.now();
    }

    /**
     * 获取当前日期
     */
    public static LocalDate getDateNow() {
        return LocalDate.now();
    }


    /**
     * date转换成String
     *
     * @param date 日期
     * @return yyyy-MM-dd
     * @author fy
     */
    public static String getStringDate(LocalDate date) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        return date.format(dateTimeFormatter);
    }

    /**
     * 获取当前时间
     *
     * @return yyyyMM
     * @author hfq
     */
    public static String getNowDateString() {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(YYYYMMDDHHMMSS);
        return dateTimeFormatter.format(LocalDateTime.now());
    }

    /**
     * 获取昨天日期
     *
     * @return yyyyMMdd
     * @author zh
     */
    public static String getYesterdayYyyyMMdd() {
        //获取前一天
        return LocalDate.now().plusDays(-1).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
    }

    /**
     * 获取昨天日期
     *
     * @param count 相隔天数：负数代表前几天，正数代表后几天
     * @return yyyyMMdd
     * @author zh
     */
    public static String getPlusDaysYyyyMMdd(int count) {
        //获取前一天
        return LocalDate.now().plusDays(count).format(DateTimeFormatter.ofPattern("yyyyMMdd"));
    }

    /**
     * 获取一段时间的每天
     *
     * @param begin yyyy-MM-dd
     * @param end   yyyy-MM-dd
     * @author zh
     */
    public static List<String> getEveryDay(String begin, String end) {
        List<String> list = new ArrayList<>();
        LocalDate startDate = LocalDate.parse(begin);
        LocalDate endDate = LocalDate.parse(end);
        long distance = ChronoUnit.DAYS.between(startDate, endDate);
        Stream.iterate(startDate, date -> date.plusDays(1)).
                limit(distance + 1).
                forEach(day -> list.add(day.format(DateTimeFormatter.ofPattern("yyyyMMdd"))));
        return list;
    }


    /**
     * 获取某月第一天
     *
     * @param date 某月
     * @return $returns LocalDate
     * @author hfq
     */
    public static LocalDate getFirstDay(LocalDate date) {
        // 获取当前月的第一天
        return date.with(TemporalAdjusters.firstDayOfMonth());
    }

    /**
     * 获取某月最后一天
     *
     * @param date 某月
     * @return $returns LocalDate
     * @author hfq
     */
    public static LocalDate getLastDay(LocalDate date) {
        // 获取当前月的最后一天
        return date.with(TemporalAdjusters.lastDayOfMonth());
    }

    /**
     * 获取两个日期的月份是否相等
     *
     * @return $returns boolean
     * @author hfq
     */
    public static boolean checkDateIsMonth(LocalDate date, LocalDate localDate) {
        if (Objects.isNull(date) || Objects.isNull(localDate)) {
            return Boolean.FALSE;
        }
        if (Objects.equals(localDate.getMonth().getValue(), date.getMonth().getValue())) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * 获取该日期当月的最后一天,并转为LocalDateTime
     *
     * @param yyyyMM 年月
     * @return java.lang.String
     * @author zh
     */
    public static LocalDate stringToLastDateYm(String yyyyMM) {
        return LocalDateTimeUtil.parseDate(yyyyMM, YYYY_MM).with(TemporalAdjusters.lastDayOfMonth());
    }


    public static LocalDate stringToFirstDateYm(String yyyyMM) {
        return LocalDateTimeUtil.parseDate(yyyyMM, YYYY_MM).with(TemporalAdjusters.firstDayOfMonth());
    }

    /**
     * 根据年月生成当月第一天数据
     *
     * @param year  年
     * @param mouth 月
     * @return $returns LocalDate
     * @author hfq
     */
    public static LocalDate getFirstLocateDateByYearMonth(String year, String mouth) {
        if (mouth.length() == 1) {
            mouth = "0" + mouth;
        }
        String date = year + "-" + mouth;
        return LocalDateTimeUtil.parseDate(date, YYYY_MM).with(TemporalAdjusters.firstDayOfMonth());
    }

    /**
     * 根据年月生成当月第一天数据
     *
     * @param year  年
     * @param mouth 月
     * @return $returns LocalDate
     * @author hfq
     */
    public static LocalDate getLastLocateDateByYearMonth(String year, String mouth) {
        if (mouth.length() == 1) {
            mouth = "0" + mouth;
        }
        String date = year + "-" + mouth;
        return LocalDateTimeUtil.parseDate(date, YYYY_MM).with(TemporalAdjusters.lastDayOfMonth());
    }

    // 获得某天最大时间 2020-02-19 23:59:59
    public static LocalDateTime getEndOfDay(LocalDateTime localDateTime) {
        return localDateTime.with(LocalTime.MAX);

    }

    // 获得某天最小时间 2020-02-17 00:00:00
    public static LocalDateTime getStartOfDay(LocalDateTime localDateTime) {
        return localDateTime.with(LocalTime.MIN);
    }

    /**
     * 判断localDate是否在startDate与endDate之间
     *
     * @param startDate 开始日期
     * @param endDate   结束日期
     * @return $returns boolean
     * @author hfq
     */
    public static boolean checkIn2Day(LocalDate localDate, LocalDate startDate, LocalDate endDate) {
        if (Objects.isNull(localDate) || Objects.isNull(startDate) || Objects.isNull(endDate)) {
            return Boolean.FALSE;
        }
        if (Objects.equals(localDate, startDate)) {
            return Boolean.TRUE;
        }
        if (Objects.equals(localDate, endDate)) {
            return Boolean.TRUE;
        }
        if (localDate.isAfter(startDate) && localDate.isBefore(endDate)) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    /**
     * 获取当年的第一天
     *
     * @param
     * @return
     */
    public static LocalDate getYearTime() {
        // 获取当前日期
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, 0);
        calendar.add(Calendar.DATE, 0);
        calendar.add(Calendar.MONTH, 0);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        Long time = calendar.getTimeInMillis();
        Instant instant = Instant.ofEpochMilli(time);
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault()).toLocalDate();
    }

    /**
     * 获取前几月凌晨时间
     *
     * @param month
     * @return
     */
    public static LocalDate getFirstDayOfMonth(Integer month) {
        LocalDateTime date = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        // 当前月份减
        LocalDateTime lastMonth = date.minusMonths(month);
        LocalDateTime firstDay = lastMonth.with(TemporalAdjusters.firstDayOfMonth()); // 获取当前月的第一天
        return firstDay.toLocalDate();
    }

    /**
     * 计算两个周期内所有日期
     *
     * @param startDate
     * @param dedDate
     * @return
     * @throws ParseException
     */
    public static List<String> getDays(String startDate, String dedDate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Long startTime = sdf.parse(startDate).getTime();
        Long endTime = sdf.parse(dedDate).getTime();

        List<String> dateList = new ArrayList<String>();
        Long oneDay = 1000 * 60 * 60 * 24L;

        Long time = startTime;
        while (time <= endTime) {
            Date d = new Date(time);
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
            String date = df.format(d);
            System.out.println(date);
            dateList.add(date);
            time += oneDay;
        }
        return dateList;
    }

    /**
     * 计算两个日期之间的所有月份
     *
     * @param startDate
     * @param endDate
     * @return
     * @throws ParseException
     */
    public static List<String> getMonthBetween(String startDate, String endDate) throws ParseException {
        List<String> result = new ArrayList<>();
        //格式化为年月
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");

        Calendar min = Calendar.getInstance();
        Calendar max = Calendar.getInstance();

        min.setTime(sdf.parse(startDate));
        min.set(min.get(Calendar.YEAR), min.get(Calendar.MONTH), 1);

        max.setTime(sdf.parse(endDate));
        max.set(max.get(Calendar.YEAR), max.get(Calendar.MONTH), 2);

        Calendar curr = min;
        while (curr.before(max)) {
            result.add(sdf.format(curr.getTime()));
            curr.add(Calendar.MONTH, 1);
        }

        return result;
    }

    /**
     * 获取count天前凌晨的时间
     *
     * @param count
     * @return
     */
    public static LocalDate getBeforeTime(int count) {
        LocalDateTime date = LocalDateTime.now().minus(count, ChronoUnit.DAYS);
        return date.withHour(0)
                .withMinute(0)
                .withSecond(0)
                .toLocalDate();
    }

    /**
     * 获取count天前凌晨的时间
     *
     * @param count
     * @return
     */
    public static LocalDateTime getLocalDateTimeBeforeTime(int count) {
        LocalDateTime date = LocalDateTime.now().minus(count, ChronoUnit.DAYS);
        return date.withHour(0)
                .withMinute(0)
                .withSecond(0)
                ;
    }

    /**
     * 获取当天的00:00:00
     *
     * @return
     */
    public static LocalDateTime getDayStart(LocalDateTime time) {
        return time.with(LocalTime.MIN);
    }


    /**
     * 获取当天的23:59:59
     *
     * @return
     */
    public static LocalDateTime getDayEnd(LocalDateTime time) {
        return time.with(LocalTime.MAX);
    }


    /**
     * 判断是否是时间格式
     *
     * @param string
     * @return
     */
    public static Date parseDate(String string) {
        if (string == null) {
            return null;
        }
        try {
            return DateUtils.parseDate(string, parsePatterns);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 获取月份
     *
     * @param dataString
     * @return
     */
    public static String geMonthByYearMonth(String dataString) {
        return dataString.split(LINK_CHAR)[1];
    }

    /**
     * 获取天
     *
     * @param dataString
     * @return
     */
    public static String getDayByYearMonthDay(String dataString) {
        return dataString.split(LINK_CHAR)[2];
    }

    /**
     * 获取统计查询时间
     *
     * @return
     */
    public static LocalDate getStatisticsNearMonthStart() {
        LocalDate startTime = DateUtil.getFirstDayOfMonth(11);
        LocalDate dateTime = LocalDate.of(2023, 5, 1);
        if (startTime.isBefore(dateTime)) {
            startTime = dateTime;
        }
        return startTime;
    }


    /**
     * 判断是否是每月第一天
     *
     * @return boolean
     */
    public static boolean ifFirstDayOfMonth() {
        LocalDate today = LocalDate.now();
        LocalDate lastDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
        return Period.between(today, lastDayOfMonth).getDays() == 0;
    }

    /**
     * 判断是否是周一
     *
     * @return boolean
     */
    public static boolean ifMonday() {
        LocalDate today = LocalDate.now();
        return Objects.equals(today.getDayOfWeek(),DayOfWeek.MONDAY);
    }

    /**
     * 判断是否是周一
     *
     * @return boolean
     */
    public static boolean ifMonday(LocalDate date) {
        return Objects.equals(date.getDayOfWeek(),DayOfWeek.MONDAY);
    }

    /**
     * 判断是否是周日
     *
     * @return boolean
     */
    public static boolean ifSunday(LocalDate date) {
        return Objects.equals(date.getDayOfWeek(),DayOfWeek.SUNDAY);
    }

    /***
     * 判断是否是季末
     *
     * @return
     * @author jianghao
     * @date 2023/10/8 10:20
     */
    public static boolean isEndOfQuarter(LocalDate localDate) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
        Date date = Date.from(instant);
        DateTime endOfQuarterDateTime = cn.hutool.core.date.DateUtil.endOfQuarter(date);
        LocalDate endOfQuarterLocalDate = LocalDate.of(endOfQuarterDateTime.year(), endOfQuarterDateTime.month() + 1, endOfQuarterDateTime.dayOfMonth());
        if (endOfQuarterLocalDate.equals(localDate)) {
            return true;
        }
        return false;
    }

    /**
     * 判断日期是否为月的第一天
     *
     * @param date 要判断的日期
     * @return 如果是月的第一天返回 true，否则返回 false
     */
    public static boolean isFirstDayOfMonth(LocalDate date) {
        return date.getDayOfMonth() == 1;
    }

    /**
     * 判断日期是否为月的最后一天
     *
     * @param date 要判断的日期
     * @return 如果是月的最后一天返回 true，否则返回 false
     */
    public static boolean isLastDayOfMonth(LocalDate date) {
        LocalDate lastDayOfMonth = date.withDayOfMonth(date.lengthOfMonth());
        return date.equals(lastDayOfMonth);
    }

    /**
     * 判断日期是否在指定的YearMonth中
     *
     * @param date      要判断的日期
     * @param yearMonth 指定的YearMonth
     * @return 如果在指定的YearMonth中返回 true，否则返回 false
     */
    public static boolean isDateInYearMonth(LocalDate date, YearMonth yearMonth) {
        YearMonth dateYearMonth = YearMonth.from(date);
        return dateYearMonth.equals(yearMonth);
    }

    /**
     * 根据日期获取月份
     *
     * @param date 日期
     * @return java.lang.String
     * @author wangchunhui
     * @date 2023/12/19 16:11
     */
    public static String getMonthByDate(LocalDate date) {
        // 判断date是否为空
        if (Objects.isNull(date)) {
            return "";
        }
        // 判断date是否为月的第一天，如果为月的第一天，+1天
        if (isFirstDayOfMonth(date)) {
            date = date.plusDays(1);
        }
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM");
        return date.format(formatter);
    }

    /**
     * 获取两个月份之间所有的月份
     * @param start
     * @param end
     * @return
     */
    public static List<YearMonth> getAllMonthsBetween(YearMonth start, YearMonth end) {
        List<YearMonth> monthsInRange = IntStream.range(start.getYear(), end.getYear() + 1)
                .boxed()
                .flatMap(year -> IntStream.range(1, 13).mapToObj(month -> YearMonth.of(year, month)))
                .filter(month -> month.isAfter(start) || month.equals(start))
                .filter(month -> month.isBefore(end) || month.equals(end))
                .collect(Collectors.toList());
        return monthsInRange;
    }

    /**
     * 获取上一周第一天
     */
    public static LocalDate getLastWeekFirstDay() {
        return LocalDate.now().minusWeeks(1).with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
    }

    // 获取去年的第一天
    public static LocalDate getLastYearFirstDay() {

        return LocalDate.now().minusYears(1).with(TemporalAdjusters.firstDayOfYear());
    }

    /**
     * 获取上一周最后一天
     */
    public static LocalDate getLastWeekLastDay() {
        return LocalDate.now().minusWeeks(1).with(TemporalAdjusters.nextOrSame(DayOfWeek.SUNDAY));
    }

    /**
      * 根据日期获取日期所在周的周一日期
      *
      * @param date
      * @return java.time.LocalDate
      * @author guoluxin
      * @date 2024/3/4 9:59
      */
    public static LocalDate getFirstDayOfWeek(LocalDate date) {
        return date.with(DayOfWeek.MONDAY);
    }

    /**
     * 根据日期获取日期所在周的周天日期
     *
     * @param date
     * @return java.time.LocalDate
     * @author guoluxin
     * @date 2024/3/4 9:59
     */
    public static LocalDate getLastDayOfWeek(LocalDate date) {
        return date.with(DayOfWeek.SUNDAY);
    }

    /**
     * localDate 日期格式化成 yyyy-MM格式
     * @param localDate
     * @return java.lang.String
     * @author zhangwei09
     * @date 2024/3/8 17:06
     */
    public static String getYyyyMmSla(LocalDate localDate) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(YYYY_MM_SLA);
        return localDate.format(formatter);
    }

    /**
     * localDate 日期格式化成 yyyy-MM-dd格式
     * @param localDate
     * @return java.lang.String
     * @author zhangwei09
     * @date 2024/3/8 17:06
     */
    public static String getYyyyMMDDSla(LocalDate localDate) {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern(YYYY_MM_DD_SLA);
        return localDate.format(formatter);
    }

    /**
     * 获取上周起始时间
     * @param date 本周日期
     * @return java.time.LocalDateTime
     * @author liuchunyu
     * @date 2024/3/27 14:43
     */
    public static LocalDateTime getLastWeekStartTime(LocalDate date) {
        LocalDate lastMondayDate = date.with(DayOfWeek.MONDAY).minusDays(1).with(DayOfWeek.MONDAY);
        return lastMondayDate.atTime(0, 0, 0);
    }

    /**
     * 获取上周结束时间
     * @param date 本周日期
     * @return java.time.LocalDateTime
     * @author liuchunyu
     * @date 2024/3/27 14:37
     */
    public static LocalDateTime getLastWeekEndTime(LocalDate date) {

        // 获取本周周一
        LocalDate mondayDate = date.with(DayOfWeek.MONDAY);
        return mondayDate.minusDays(1).atTime(23, 59, 59);
    }

}
